package com.yugao.fintech.antelope.pay.common.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yugao.fintech.antelope.pay.common.mapper.TransferOrderMapper;
import com.yugao.fintech.antelope.pay.common.service.TransferOrderService;
import com.yugao.fintech.antelope.pay.model.entity.TransferOrder;
import com.yugao.fintech.antelope.pay.model.rqrs.TransferOrderQL;
import com.yugao.fintech.framework.assistant.utils.StringUtils;
import com.yugao.fintech.framework.core.page.PageModel;
import com.yugao.fintech.framework.core.page.TableSupport;
import com.yugao.fintech.framework.mybatisplus.utils.PageUtil;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;


@Service
public class TransferOrderServiceImpl extends ServiceImpl<TransferOrderMapper, TransferOrder>
        implements TransferOrderService {

    @Override
    public boolean updateInit2Ing(String transferNo) {
        TransferOrder updateRecord = new TransferOrder();
        updateRecord.setStatus(TransferOrder.STATE_ING);
        return update(updateRecord, new LambdaUpdateWrapper<TransferOrder>()
                .eq(TransferOrder::getTransferNo, transferNo).eq(TransferOrder::getStatus, TransferOrder.STATE_INIT));
    }

    @Override
    public boolean updateIng2Success(String transferNo, String channelOrderNo) {
        TransferOrder updateRecord = new TransferOrder();
        updateRecord.setStatus(TransferOrder.STATE_SUCCESS);
        updateRecord.setChannelOrderNo(channelOrderNo);
        updateRecord.setSuccessTime(new Date());

        //更新转账订单表数据
        return update(updateRecord, new LambdaUpdateWrapper<TransferOrder>()
                .eq(TransferOrder::getTransferNo, transferNo).eq(TransferOrder::getStatus, TransferOrder.STATE_ING));
    }

    @Override
    public boolean updateIng2Fail(String transferNo, String channelOrderNo, String channelErrCode, String channelErrMsg) {
        TransferOrder updateRecord = new TransferOrder();
        updateRecord.setStatus(TransferOrder.STATE_FAIL);
        updateRecord.setErrCode(channelErrCode);
        updateRecord.setErrMsg(channelErrMsg);
        updateRecord.setChannelOrderNo(channelOrderNo);

        return update(updateRecord, new LambdaUpdateWrapper<TransferOrder>()
                .eq(TransferOrder::getTransferNo, transferNo).eq(TransferOrder::getStatus, TransferOrder.STATE_ING));
    }

    @Override
    public boolean updateIng2SuccessOrFail(String transferNo, String updateStatus, String channelOrderNo, String channelErrCode, String channelErrMsg) {
        if (TransferOrder.STATE_ING.equals(updateStatus)) {
            return true;
        } else if (TransferOrder.STATE_SUCCESS.equals(updateStatus)) {
            return updateIng2Success(transferNo, channelOrderNo);
        } else if (TransferOrder.STATE_FAIL.equals(updateStatus)) {
            return updateIng2Fail(transferNo, channelOrderNo, channelErrCode, channelErrMsg);
        }
        return false;
    }

    @Override
    public TransferOrder queryMchOrder(String mchNo, String mchOrderNo, String transferNo) {
        if (StringUtils.isNotEmpty(transferNo)) {
            return getOne(TransferOrder.lqw().eq(TransferOrder::getMchNo, mchNo).eq(TransferOrder::getTransferNo, transferNo));
        } else if (StringUtils.isNotEmpty(mchOrderNo)) {
            return getOne(TransferOrder.lqw().eq(TransferOrder::getMchNo, mchNo).eq(TransferOrder::getMchOrderNo, mchOrderNo));
        } else {
            return null;
        }
    }

    @Override
    public IPage<TransferOrder> pageTransferOrder(TransferOrderQL query) {
        PageModel page = TableSupport.buildPageRequest();
        LocalDateTime beginTime = Optional.ofNullable(page.getBeginDate()).map(DateTime::toLocalDateTime).orElse(null);
        LocalDateTime endTime = Optional.ofNullable(page.getEndDate()).map(DateTime::toLocalDateTime).orElse(null);

        LambdaQueryWrapper<TransferOrder> lqw = TransferOrder.lqw()
                .eq(StringUtils.isNotEmpty(query.getTransferNo()), TransferOrder::getTransferNo, query.getTransferNo())
                .eq(StringUtils.isNotEmpty(query.getChannelOrderNo()), TransferOrder::getChannelOrderNo, query.getChannelOrderNo())
                .eq(StringUtils.isNotEmpty(query.getAppId()), TransferOrder::getAppId, query.getAppId())
                .eq(StringUtils.isNotEmpty(query.getStatus()), TransferOrder::getStatus, query.getStatus())
                .eq(StringUtils.isNotEmpty(query.getMchNo()), TransferOrder::getMchNo, query.getMchNo())
                .eq(StringUtils.isNotEmpty(query.getMchOrderNo()), TransferOrder::getMchOrderNo, query.getMchOrderNo());
        lqw.and(StringUtils.isNotEmpty(query.getUnionOrderNo()), e -> {
            e.eq(TransferOrder::getTransferNo, query.getUnionOrderNo()).or()
                    .eq(TransferOrder::getChannelOrderNo, query.getUnionOrderNo()).or()
                    .eq(TransferOrder::getMchOrderNo, query.getUnionOrderNo());
        });

        lqw.ge(Objects.nonNull(beginTime), TransferOrder::getCreatedAt, beginTime);
        lqw.ge(Objects.nonNull(endTime), TransferOrder::getCreatedAt, endTime);
        lqw.orderByDesc(TransferOrder::getCreatedAt);
        return this.page(PageUtil.to(page), lqw);
    }
}
